import React, { useEffect, useState } from "react";
import type { TableProps } from "antd";
import { Button, Popconfirm, Table } from "antd";
import { Column, TableData } from "..";
import { editableComponents } from "./antdEditTable";

type ColumnTypes = Exclude<TableProps<AntdTableData>["columns"], undefined>;

export type AntdTableData =
  | {
      key: number;
      inventory: number;
      price: number;
    }
  | TableData;

type AntdTableHeader = ColumnTypes[number] & {
  editable?: boolean;
  dataIndex: string;
};

function SkuAdminTable({
  columns: originColumns,
  data: originData,
  onFinish,
}: {
  columns: Column[];
  data: TableData[];
  onFinish: (dataSource: AntdTableData[]) => void;
}) {
  const [columns, setColumns] = useState<AntdTableHeader[]>([]);
  const [dataSource, setDataSource] = useState<AntdTableData[]>([]);

  const getColumns = () => {
    const col = applyAntdTableColumns(originColumns);
    const editableColumns = addEditableColumns(col) as AntdTableHeader[];
    return editableColumns;
  };

  useEffect(() => {
    const data = applyAntdTableData(originData);
    setDataSource(data);
  }, [originData]);

  useEffect(() => {
    const col = getColumns();
    setColumns(col);
  }, [dataSource]);

  const handleDelete = (key: React.Key) => {
    const newDataSource = dataSource.filter(
      (item: AntdTableData) => item.key !== key
    );
    setDataSource(newDataSource);
  };

  const applyAntdTableColumns = (columns: Column[]) => {
    const col = columns.map((item: Column) => {
      return {
        title: item.name,
        dataIndex: item.name.toLowerCase(),
      };
    });
    const inventory = {
      title: "inventory",
      dataIndex: "inventory",
      width: "100px",
      editable: true,
    };
    const price = {
      title: "price",
      dataIndex: "price",
      width: "100px",
      editable: true,
    };
    const operation = {
      title: "operation",
      dataIndex: "operation",
      width: "100px",
      render: (_: unknown, record: { key: React.Key }) => {
        return dataSource.length >= 1 ? (
          <Popconfirm
            title="Sure to delete?"
            onConfirm={() => handleDelete(record.key)}
          >
            <a>Delete</a>
          </Popconfirm>
        ) : null;
      },
    };
    const result = [...col, inventory, price, operation];
    return result;
  };

  const applyAntdTableData = (data: TableData[]) => {
    const res = data.map((item, index) => {
      return {
        ...item,
        key: index,
        // inventory: 0,
        // price: 0,
        inventory: index + 1,
        price: index + 1,
      };
    });
    return res;
  };

  // create editable columns
  const addEditableColumns = (columns: AntdTableHeader[]) => {
    const result = columns.map((col) => {
      if (!col.editable) {
        return col;
      }
      return {
        ...col,
        onCell: (record: AntdTableData) => ({
          record,
          editable: col.editable,
          dataIndex: col.dataIndex,
          title: col.title,
          handleSave,
        }),
      };
    });
    return result;
  };

  const handleSave = (row: AntdTableData) => {
    const newData = [...dataSource];
    const index = newData.findIndex((item) => row.key === item.key);
    const item = newData[index];
    newData.splice(index, 1, {
      ...item,
      ...row,
    });
    setDataSource(newData);
  };

  const createFrontEndPage = () => {
    onFinish(dataSource);
  };

  return (
    <>
      {dataSource.length > 0 && (
        <>
          <Table<AntdTableData>
            components={editableComponents}
            rowClassName={() => "editable-row"}
            bordered
            dataSource={dataSource}
            columns={columns as ColumnTypes}
          />
          <Button type="primary" onClick={() => createFrontEndPage()}>
            Create Front End Page
          </Button>
        </>
      )}
    </>
  );
}

export default SkuAdminTable;
